﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebChat.Models;
using System.Web;

namespace WebChat.Controllers
{
    public class RoomApiController : ApiController
    {
        // GET api/<controller>
        private MessageRepository messageRep = new MessageRepository();
        private UserRepository userRep = new UserRepository();
        private ChannelRepository channelRep = new ChannelRepository();

        /// <summary>
        /// Returnerer en liste over brukere i chat
        /// </summary>
        /// <param name="id">Chatroom id</param>
        /// <returns></returns>
        public IEnumerable<aspnet_User> GetUsersInChat(int id)
        {
            return userRep.usersInChatroom(id);//Bruker UserRepository for å hente lista
        }

        /// <summary>
        /// Fjerner bruker fra chat
        /// </summary>
        /// <param name="id">Chatroom id</param>
        public void RemoveUserFromChat(int id)
        {
            //Henter bruker fra aktuell chat
            string usrname = User.Identity.Name;
            if (!usrname.Equals(""))//hvis bruker er logget av skal ikke koden under kjøres
            {
                UsersInChatroom uInC = userRep.getUserInChat(id, userRep.getUserId(User.Identity.Name));
                if (uInC != null)//Hvis den eksisterer, slettes den
                    userRep.removeUserInChat(uInC);
            }
        }

        /// <summary>
        /// Legger til en bruker i chat
        /// </summary>
        /// <param name="id">Chatroom id</param>
        /// <returns>true om bruker er innlogget i aktuell chat</returns>
        public bool AddUserToChat(int id)
        {
            UsersInChatroom uInC = new UsersInChatroom();//Oppretter ny kolonne for bruker
            uInC.userId = userRep.getUserId(User.Identity.Name);//Henter brukerID via brukernavn
            uInC.chatId = id;//ChatroomID er lik inputparameter
            uInC.ActiveOnPhone = "false";//Innlogget via telefon settes til "false"
            if (!userRep.isUserInChat(uInC.chatId, uInC.userId))
            {
                //hvis denne brukeren ikke allerede er innlogget
                userRep.addUserToChat(uInC);//Legges han til 
                return false;
            }
            else
                return true;
        }

        /// <summary>
        ///  POST api/<controller>
        ///  Henter de besjedene som ikke er hentet
        /// </summary>
        /// <param name="id">Chatroom ID</param></param>
        /// <param name="count">Antall beskjeder som er kommet</param>
        /// <returns></returns>
        public IEnumerable<Message> GetMessage(int id, int count)
        {
            IEnumerable<Message> mess = messageRep.getNewMessages(id, count);
            return mess;
        }

        // PUT api/<controller>/5
        /// <summary>
        /// Skjekker først om det er kommet noen ny beskjed via tlf
        /// Hvis det er kommet legges den til i databasen. 
        /// Returnerer antall beskjeder
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int GetCount(int id)
        {
            CheckForSMS(id);
            return messageRep.getNoOfMessagesInroom(id);
        }

        // DELETE api/<controller>/5
        public void Delete(int id)
        {
        }


        /// <summary>
        /// Hvis det har kommet en melding, skjekker denne metoden hva meldingen inneholder.
        /// Hvis den inneholder "start", får bruker tilsendt nye meldinger og han kan sende meldinger 
        /// til chatten. Hvis meldingen inneholder stop får ikke brukeren delta i chatten lengre.
        /// </summary>
        /// <param name="id"></param>
        private void CheckForSMS(int id)
        {
            string chatroomId = id + "";
            string sms = GetSms(chatroomId);
            if (ParseJson(element.STATUS, sms) != "NoSuchMessage")//Hvis status er NoSuchMessage, har det ikke kommet inn noen ny beskjed.
            {
                string phoneNumber = ParseJson(element.SEND, sms);//henter avsenders telefonnummer
                Guid author = userRep.GetUserIdFromPhone(phoneNumber);//henter avsenders bruker-id
                string text = ParseJson(element.TEXT, sms).Substring(chatroomId.Length + 1);//henter beskjeden minus kodeordet som i dette tilfellet er chat-id

                if (text.Equals("start"))
                    SetUserActiveOnPhone(id, true, phoneNumber);//Hvis meldingen er "start", logges bruker inn og kan motta og sende meldinger til chatrommet
                else if (text.Equals("stop") && GetUserActiveOnPhone(id, phoneNumber) == true)
                    SetUserActiveOnPhone(id, false, phoneNumber);//Hvis meldingen inneholder stop, logges bruker ut, og kan ikke lengre motta eller sende meldinger
                else if (GetUserActiveOnPhone(id, phoneNumber))
                {
                    Message message = new Message();//Oppretter beskjed som skal legges til i database
                    message.name = ParseJson(element.STATUS, sms);
                    message.Chatroom = id;
                    message.Message1 = text;
                    message.AuthorId = author;
                    message.Date = System.DateTime.Now;
                    messageRep.addMessage(message);//Legger til beskjed i databse
                }
            }
        }

        /// <summary>
        /// Henter sms fra sms server
        /// </summary>
        /// <returns></returns>
        private string GetSms(string code)
        {
            string uri = "http://malmen.hin.no/pswin/SMS/ChatInCode/" + code;//Koden i dette tilfellet er chat-id

            WebClient wc = new WebClient();
            string output = wc.DownloadString(uri);//henter meldingen ned som Json-string

            return output;
        }

        /// <summary>
        /// Verdier som brukes for å hente ut enkelte elementer i sms
        /// </summary>
        enum element { ID, SEND, RECIVE, TEXT, DATE, STATUS }

        private string ParseJson(element e, string input)
        {
            //Rensker først bort den delen av stringen som ikke trengs
            input = input.Replace("{", "");
            input = input.Replace("}", "");
            input = input.Replace("\"", "");
            string[] output = input.Split(',');//skiller hvert element
            switch (e)//Returnerer ønsket del av meldingen
            {
                case element.ID:
                    return output[0].Split(':')[1];
                case element.SEND:
                    return output[1].Split(':')[1];
                case element.RECIVE:
                    return output[2].Split(':')[1];
                case element.TEXT:
                    return output[3].Split(':')[1];
                case element.DATE:
                    return output[4].Split(':')[1];
                default:
                    return output[5].Split(':')[1];
            }
        }

        /// <summary>
        /// Setter en variabel i UsersInChatroom-tabellen til enten "true" eller "false"
        /// Skrevet slik at når bruker entrer et chatroom via nettsiden, skal 
        /// brker ikke motta meldinger på telefon.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="activeOnPhone"></param>
        /// <param name="phoneNumber"></param>
        private void SetUserActiveOnPhone(int id, bool activeOnPhone, string phoneNumber)
        {
            if (activeOnPhone)
            {
                Guid userID = userRep.GetUserIdFromPhone(phoneNumber);//Finner bruker-id via telefonnummer
                bool canEnter = false;

                Chatroom chatroom = channelRep.showChatroom(id);//henter det aktuelle chatrommet
                if (chatroom.IsPublic.Equals("Yes"))//Hvis chatten er public, får bruker tilgang
                    canEnter = true;
                else//Hvis ikke må det skjekkes om bruker er på medlemslista
                {
                    List<Permitted_user> pUsers = userRep.showUserWithChatroom(id);//henter liste med tillatte brukere
                    foreach (Permitted_user user in pUsers)
                        if (user.UserId == userID)//Hvis brukeren er på lista
                            canEnter = true;//Kan han bli logget inn
                }
                UsersInChatroom uinc = new UsersInChatroom();
                uinc.userId = userID;
                uinc.chatId = id;
                uinc.ActiveOnPhone = "true";

                //Bruker får ikke delta per telefon hvis han allerede er pålogget i aktuellt chatroom
                if (!userRep.isUserInChat(uinc.chatId, uinc.userId) && canEnter)
                {
                    userRep.addUserToChat(uinc);
                }
            }
            else//Hvis activeOnPhone == false
            {
                UsersInChatroom uinc = userRep.getUserInChat(id,
                    userRep.GetUserIdFromPhone(phoneNumber));

                //uinc.ActiveOnPhone = "false";
                userRep.removeUserInChat(uinc);//Logges bruker av chat
            }
        }

        /// <summary>
        /// Returnerer true om bruker er innlogget via telefon
        /// </summary>
        /// <param name="id"></param>
        /// <param name="phoneNumber"></param>
        /// <returns></returns>
        private bool GetUserActiveOnPhone(int id, string phoneNumber)
        {
            UsersInChatroom uinc = userRep.getUserInChat(id,
                userRep.GetUserIdFromPhone(phoneNumber));

            if (uinc != null && uinc.ActiveOnPhone.Replace(" ", "").Equals("true"))
                return true;
            else return false;
        }
    }
}